package com.sky.controller.user;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sky.constant.JwtClaimsConstant;
import com.sky.constant.WechatConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.properties.JwtProperties;
import com.sky.properties.WeChatProperties;
import com.sky.result.Result;
import com.sky.result.WechatLoginResult;
import com.sky.service.UserService;
import com.sky.utils.JwtUtil;
import com.sky.vo.UserLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Slf4j
@Api(tags = "用户登录接口")
@RestController
@RequestMapping("/user/user")
public class UserController {

	@Autowired
	JwtProperties jwtProperties;

	@Autowired
	WeChatProperties weChatProperties;

	@Autowired
	UserService userService;


	@ApiOperation("用户登录接口")
	@PostMapping("/login")
	public Result login(@RequestBody UserLoginDTO userLoginDTO) {
		log.info("wx授权码:{}",userLoginDTO.getCode());

		//实例化HttpClient端
		HttpClient httpClient = HttpClientBuilder.create().build();
		URIBuilder uriBuilder;
		URI uri;
		HttpResponse resp;
		String ret;
		try
		{
			//构建 URI(第三方接口) && 请求参数列表
			uriBuilder = new URIBuilder("https://api.weixin.qq.com/sns/jscode2session");
			List<NameValuePair> ln = new LinkedList<>();
			//小程序id
			ln.add(new BasicNameValuePair(WechatConstant.APPID, weChatProperties.getAppid()));
			//小程序密钥
			ln.add(new BasicNameValuePair(WechatConstant.SECRET_KEY, weChatProperties.getSecret()));
			//wx登录授权码,前端传入
			ln.add(new BasicNameValuePair(WechatConstant.JS_CODE, userLoginDTO.getCode()));
			//token名字,默认
			ln.add(new BasicNameValuePair(WechatConstant.GRANT_TYPE, weChatProperties.getGrant_type()));
			log.info("构建请求参数列表:{}",ln);
			//构建uri
			uri = uriBuilder.addParameters(ln).build();
		} catch (URISyntaxException e)
		{
			throw new RuntimeException(e);
		}

		//构建HTTP Get 请求
		HttpGet httpGet = new HttpGet();
		httpGet.setURI(uri);

		//向微信登录接口发送请求
		try
		{
			resp = httpClient.execute(httpGet);
		//解析响应,获取用户唯一标识openid
			ret = EntityUtils.toString(resp.getEntity(), StandardCharsets.UTF_8.name());
		} catch (IOException e)
		{
			throw new RuntimeException(e);
		}
		log.info("ret:{}",ret);

		//使用json反序列化响应数据
		WechatLoginResult wechatLoginResult;
		try
		{
			wechatLoginResult = new ObjectMapper().readValue(ret, WechatLoginResult.class);
		} catch (JsonProcessingException e)
		{
			throw new RuntimeException(e);
		}

		//查找数据库是否存在该用户
		User user = userService.userByOpenId(wechatLoginResult.getOpenid());
		if(user == null)
		{
			user = new User();
			//若无,则为新用户
			log.info("插入用户:{}",user);
			user.setOpenid(wechatLoginResult.getOpenid());
			log.info("当前用户为新用户,插入数据");
			userService.insert(user);
		}
		else
			log.info("当前用户非新用户");
		//生成authorization作为会话令牌,返回用户端
		//构建令牌加密数据
		Map<String, Object> claims = new HashMap<>();
		claims.put(JwtClaimsConstant.USER_ID, user.getId());
		claims.put(WechatConstant.SESSION_KEY, wechatLoginResult.getSession_key());
		//生成令牌
		String token = JwtUtil.createJWT(
				jwtProperties.getUserSecretKey(),
				jwtProperties.getUserTtl(),
				claims);

		UserLoginVO userLoginVO = UserLoginVO.builder()
											 .id(user.getId())
											 .token(token)
											 .openid(user.getOpenid()).build();
		return Result.success(userLoginVO);
	}

}
